package center.wxp.sentinel;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.openfeign.EnableFeignClients;

import java.util.ArrayList;
import java.util.List;

/**
 * 把流量作为切入点，从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性
 */
@EnableFeignClients
@SpringBootApplication
@RefreshScope
@EnableDiscoveryClient
public class SpringAlibabaSentinelApplication {
    private static final String KEY = "/hi";

    public static void main(String[] args) {
        SpringApplication.run(SpringAlibabaSentinelApplication.class, args);
    }

    /**
     * 流量控制规则 (FlowRule)
     */
    private static void initFlowQpsRule() {
        List<FlowRule> rules = new ArrayList<FlowRule>();
        FlowRule rule1 = new FlowRule();
        rule1.setResource(KEY);
        //限流阈值
        rule1.setCount(1);
        rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控针对的调用来源,default，代表不区分调用来源
        rule1.setLimitApp("default");
        //流控效果（直接拒绝/WarmUp/匀速+排队等待），不支持按调用关系限流
        rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
        //调用关系限流策略：直接、链路、关联
        rule1.setStrategy(RuleConstant.STRATEGY_DIRECT);
        rules.add(rule1);
        FlowRuleManager.loadRules(rules);
    }


    /**
     * 几种熔断策略:
     * 1、慢调用比例 (SLOW_REQUEST_RATIO)
     */
    private static void initDegradeRule() {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource(KEY);
        // 慢调用比例模式下为慢调用临界 RT（超出该值计为慢调用）单位毫秒,；异常比例/异常数模式下为对应的阈值
        rule.setCount(10);
        //熔断策略，支持慢调用比例/异常比例/异常数策略(默认：慢调用比例)
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        //熔断时长，单位为 s
        rule.setTimeWindow(10);
        //熔断触发的最小请求数，请求数小于该值时即使异常比率超出阈值也不会熔断
        rule.setMinRequestAmount(100);
        //统计时长（单位为 ms）
        rule.setStatIntervalMs(1000);
        //慢调用比例阈值，仅慢调用比例模式有效
        rule.setSlowRatioThreshold(0.7);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    /**
     * 系统自适应
     */
    private static void initSystemRule() {
        List<SystemRule> rules = new ArrayList<>();
        SystemRule rule = new SystemRule();
        rule.setHighestSystemLoad(10);
        rule.setMaxThread(100);
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }
}
